package com.uduemc.biso.node.module.controller;

import com.uduemc.biso.core.utils.RestResult;
import com.uduemc.biso.node.core.dto.FeignFindInfosByHostSiteAndSystemTypeIds;
import com.uduemc.biso.node.core.entities.SSystem;
import com.uduemc.biso.node.module.service.SSystemService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PageableDefault;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/s-system")
public class SSystemController {

    private static final Logger logger = LoggerFactory.getLogger(SSystemController.class);

    @Autowired
    private SSystemService sSystemServiceImpl;

    @PostMapping("/insert")
    public RestResult insert(@Valid @RequestBody SSystem sSystem, BindingResult errors) {
        logger.info("insert: " + sSystem.toString());
        if (errors.hasErrors()) {
            Map<String, Object> message = new HashMap<>();
            for (FieldError fieldError : errors.getFieldErrors()) {
                String field = fieldError.getField();
                String defaultMessage = fieldError.getDefaultMessage();
                message.put(field, defaultMessage);
            }

            return RestResult.error(message);
        }
        SSystem data = sSystemServiceImpl.insertSystem(sSystem);
        return RestResult.ok(data, SSystem.class.toString());
    }

    @PutMapping("/update-by-id")
    public RestResult updateById(@Valid @RequestBody SSystem sSystem, BindingResult errors) {
        logger.info("updateById: " + sSystem.toString());
        if (errors.hasErrors()) {
            Map<String, Object> message = new HashMap<>();
            for (FieldError fieldError : errors.getFieldErrors()) {
                String field = fieldError.getField();
                String defaultMessage = fieldError.getDefaultMessage();
                message.put(field, defaultMessage);
            }

            return RestResult.error(message);
        }
        SSystem findOne = sSystemServiceImpl.findOne(sSystem.getId());
        if (findOne == null) {
            return RestResult.noData();
        }
        SSystem data = sSystemServiceImpl.updateById(sSystem);
        return RestResult.ok(data, SSystem.class.toString());
    }

    @GetMapping("/find-one/{id:\\d+}")
    public RestResult findOne(@PathVariable("id") Long id) {
        SSystem data = sSystemServiceImpl.findOne(id);
        if (data == null) {
            return RestResult.noData();
        }
        return RestResult.ok(data, SSystem.class.toString());
    }

    @GetMapping(value = {"/find-all"})
    public RestResult findAll(@PageableDefault(page = 0, size = 12) Pageable pageable) {
        logger.info("pageable: " + pageable.toString());
        List<SSystem> findAll = sSystemServiceImpl.findAll(pageable);
        return RestResult.ok(findAll, SSystem.class.toString(), true);
    }

    @GetMapping("/delete-by-id/{id:\\d+}")
    public RestResult deleteById(@PathVariable("id") Long id) {
        SSystem findOne = sSystemServiceImpl.findOne(id);
        if (findOne == null) {
            return RestResult.ok();
        }
        sSystemServiceImpl.deleteById(id);
        return RestResult.ok(findOne);
    }

    @GetMapping("/find-ssystem-by-host-site-id/{hostId:\\d+}/{siteId:\\d+}")
    public RestResult findSSystemByHostSiteId(@PathVariable("hostId") Long hostId, @PathVariable("siteId") Long siteId) {
        if (hostId == null || hostId.longValue() < 1 || siteId == null || siteId.longValue() < 0) {
            return RestResult.error();
        }
        List<SSystem> list = sSystemServiceImpl.findSSystemByHostSiteId(hostId, siteId);
        if (CollectionUtils.isEmpty(list)) {
            return RestResult.noData();
        }
        return RestResult.ok(list, SSystem.class.toString(), true);
    }

    /**
     * 通过参数过滤获取 SSystem 数据，注意 formId 这个参数
     *
     * @param hostId
     * @param siteId
     * @param formId formId 为 -2 则获取的是 formId > 0 的过滤数据，为 -1 则不对这个参数进行过滤，为 0 获取的是 formId == 0 的过滤数据
     * @return
     */
    @GetMapping("/find-ssystem-by-host-site-form-id/{hostId:\\d+}/{siteId:\\d+}/{formId:-?\\d+}")
    public RestResult findSSystemByHostSiteFormId(@PathVariable("hostId") long hostId, @PathVariable("siteId") long siteId, @PathVariable("formId") long formId) {
        if (hostId < 1 || siteId < 0) {
            return RestResult.error();
        }
        List<SSystem> list = sSystemServiceImpl.findSSystemByHostSiteFormId(hostId, siteId, formId);
        if (CollectionUtils.isEmpty(list)) {
            return RestResult.noData();
        }
        return RestResult.ok(list, SSystem.class.toString(), true);
    }

    /**
     * 完整的讲一个系统以及系统当中的所有数据从数据库中删除
     *
     * @param id
     * @return
     */
    @GetMapping("/delete-system-by-id/{id:\\d+}")
    public RestResult deleteSystemById(@PathVariable("id") Long id) {
        SSystem findOne = sSystemServiceImpl.findOne(id);
        if (findOne == null) {
            return RestResult.ok();
        }
        boolean deleteSystemById = sSystemServiceImpl.deleteSystemBySSystem(findOne);
        if (!deleteSystemById) {
            return RestResult.error();
        }
        return RestResult.ok(findOne);
    }

    /**
     * 完整的将一个系统以及系统当中的所有数据从数据库中删除
     *
     * @param id
     * @return
     */
    @GetMapping("/delete-system-by-id-host-site-id/{id:\\d+}/{hostId:\\d+}/{siteId:\\d+}")
    public RestResult deleteSystemByIdHostSiteId(@PathVariable("id") long id, @PathVariable("hostId") long hostId, @PathVariable("siteId") long siteId) {
        SSystem findOne = sSystemServiceImpl.findSSystemByIdHostSiteId(id, hostId, siteId);
        if (findOne == null) {
            return RestResult.ok();
        }
        boolean deleteSystemById = sSystemServiceImpl.deleteSystemBySSystem(findOne);
        if (!deleteSystemById) {
            return RestResult.error();
        }
        return RestResult.ok(findOne);
    }

    /**
     * 通过 id、hostId、siteId 获取s_system数据
     *
     * @param id
     * @param hostId
     * @param siteId
     * @return
     */
    @GetMapping("/find-by-id-and-host-site-id/{id:\\d+}/{hostId:\\d+}/{siteId:\\d+}")
    public RestResult findByIdAndHostSiteId(@PathVariable("id") long id, @PathVariable("hostId") long hostId, @PathVariable("siteId") long siteId) {
        SSystem findOne = sSystemServiceImpl.findSSystemByIdHostSiteId(id, hostId, siteId);
        if (findOne == null) {
            return RestResult.noData();
        }
        return RestResult.ok(findOne);
    }

    /**
     * 通过 hostId、siteId、systemTypeIds 获取 系统列表数据
     *
     * @param feignFindInfosByHostSiteAndSystemTypeIds
     * @return
     */
    @PostMapping("/find-infos-by-host-site-and-systemtypeids")
    public RestResult findInfosByHostSiteAndSystemTypeIds(
            @Valid @RequestBody FeignFindInfosByHostSiteAndSystemTypeIds feignFindInfosByHostSiteAndSystemTypeIds) {
        long hostId = feignFindInfosByHostSiteAndSystemTypeIds.getHostId();
        long siteId = feignFindInfosByHostSiteAndSystemTypeIds.getSiteId();
        List<Long> systemTypeIds = feignFindInfosByHostSiteAndSystemTypeIds.getSystemTypeIds();
        List<SSystem> data = sSystemServiceImpl.findInfosBySystemTypeIds(hostId, siteId, systemTypeIds);
        if (CollectionUtils.isEmpty(data)) {
            return RestResult.noData();
        }
        return RestResult.ok(data);
    }

    /**
     * 通过 hostId 获取系统总数
     */
    @GetMapping("/total-by-host-id/{hostId:\\d+}")
    public RestResult totalByHostId(@PathVariable("hostId") long hostId) {
        if (hostId < 1) {
            return RestResult.error();
        }
        int total = sSystemServiceImpl.totalByHostId(hostId);
        return RestResult.ok(total, Integer.class.toString());
    }

    /**
     * 通过 hostId、siteId 获取系统总数
     */
    @GetMapping("/total-by-host-site-id/{hostId:\\d+}/{siteId:\\d+}")
    public RestResult totalByHostSiteId(@PathVariable("hostId") long hostId, @PathVariable("siteId") long siteId) {
        if (hostId < 1 || siteId < 1) {
            return RestResult.error();
        }
        int total = sSystemServiceImpl.totalByHostSiteId(hostId, siteId);
        return RestResult.ok(total, Integer.class.toString());
    }

    /**
     * 文章系统使用数量统计
     *
     * @param trial  是否试用 -1:不区分 0:试用 1:正式
     * @param review 制作审核 -1:不区分 0-未审核 1-审核通过 2-审核不通过
     */
    @GetMapping("/query-article-count/{trial:-?\\d+}/{review:-?\\d+}")
    public RestResult queryArticleCount(@PathVariable("trial") int trial, @PathVariable("review") int review) {
        Integer count = sSystemServiceImpl.querySystemTypeCount(trial, review, 1L);
        return RestResult.ok(count, Integer.class.toString());
    }

    /**
     * 产品系统使用数量统计
     *
     * @param trial  是否试用 -1:不区分 0:试用 1:正式
     * @param review 制作审核 -1:不区分 0-未审核 1-审核通过 2-审核不通过
     */
    @GetMapping("/query-produce-count/{trial:-?\\d+}/{review:-?\\d+}")
    public RestResult queryProduceCount(@PathVariable("trial") int trial, @PathVariable("review") int review) {
        Integer count = sSystemServiceImpl.querySystemTypeCount(trial, review, 3L);
        return RestResult.ok(count, Integer.class.toString());
    }
}
